package edu.spbsu.nonsm00th.computgeom.util;

import edu.spbsu.nonsm00th.algorithms.sort.Comparator;
import edu.spbsu.nonsm00th.computgeom.sort.impl.ComparatorDNCartesian;
import edu.spbsu.nonsm00th.model.Point;
import edu.spbsu.nonsm00th.model.enums.Ratio;
import edu.spbsu.nonsm00th.util.Precondition;
import java.util.List;

/**
 * Arbitrary demension helper class.
 *
 * @author mukhadin
 */
public class DNUtil {

    public static Point findCartesianMinimum(final List<Point> list) {//TODO:final List - implement own structure (maybe with lock)
        int index = findCartesianMinimumIndex(list);
        return list.get(index);
    }

    /**
     * Returns the index of cartesian minimum poin in the list.
     * @param list the list
     * @return the index
     */
    public static int findCartesianMinimumIndex(final List<Point> list) {
        Precondition.argsNotNull(list);
        Precondition.check(0 != list.size(), "List of points should contain at least 1 element");

        Comparator<Point> comparatorCartesian = new ComparatorDNCartesian();
        Point min = list.get(0);
        int index = 0;
        for (int i = 0; i < list.size(); i++) {
            Point next = list.get(i);
            if (Ratio.LESS == comparatorCartesian.compare(next, min)) {
                min = next;
                index = i;
            }
        }
        return index;
    }

    /**
     * Calculates the distance between points <code>p1</code> and
     * <code>p2</code>.
     *
     * TODO: move to PointUtil
     *
     * @param p1 the point
     * @param p2 the point
     * @return the distance
     */
    public static double getDistance(Point p1, Point p2) {
        Precondition.argsNotNull(p1, p2);
        Precondition.check(p1.getDimension() == p2.getDimension(), "Dimension of points should be same");

        double d = 0.0;
        for (int i = 0; i < p1.getDimension(); i++) {
            d += p1.getXi(i) * p1.getXi(i) + p2.getXi(i) * p2.getXi(i);
        }
        return Math.sqrt(d);
    }

}
